package xyz.bali16.module.team.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gitee.starblues.bootstrap.annotation.AutowiredType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import xyz.bali16.application.config.prop.AuthProp;
import xyz.bali16.application.core.enums.ApiEnum;
import xyz.bali16.application.core.model.Result;
import xyz.bali16.application.core.utils.AuthUtils;
import xyz.bali16.application.entity.Role;
import xyz.bali16.application.entity.User;
import xyz.bali16.application.entity.UserRole;
import xyz.bali16.application.model.PageParam;
import xyz.bali16.application.service.RoleService;
import xyz.bali16.application.service.UserRoleService;
import xyz.bali16.application.service.UserService;
import xyz.bali16.module.team.entity.Team;
import xyz.bali16.module.team.entity.UserTeam;
import xyz.bali16.module.team.model.TeamAddParam;
import xyz.bali16.module.team.model.TeamPageParam;
import xyz.bali16.module.team.model.TeamUpdateParam;
import xyz.bali16.module.team.model.request.TeamJoinRequest;
import xyz.bali16.module.team.model.request.TeamQuitRequest;
import xyz.bali16.module.team.model.vo.TeamUserVO;
import xyz.bali16.module.team.service.TeamService;
import xyz.bali16.module.team.service.UserTeamService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static xyz.bali16.application.core.model.Result.*;
import static xyz.bali16.application.core.model.Result.failure;

/**
 * @author bali2 on 9/3/2023.
 * @version 1.0
 */
@RestController
@RequestMapping(BaseController.API + "team")
@Api(tags = "队伍接口")
public class TeamController extends BaseController {
    @Autowired
    TeamService teamService;

    @Autowired
    @AutowiredType(AutowiredType.Type.PLUGIN_MAIN)
    UserService userService;
    @Autowired
    @AutowiredType(AutowiredType.Type.PLUGIN_MAIN)
    RoleService roleService;
    @Autowired
    @AutowiredType(AutowiredType.Type.PLUGIN_MAIN)
    UserRoleService userRoleService;
    @Autowired
    @AutowiredType(AutowiredType.Type.PLUGIN_MAIN)
    AuthProp authProp;

    @Autowired
    private UserTeamService userTeamService;

    @GetMapping
    @ApiOperation("分页条件查询队伍列表")
    //@PreAuthorize("@auth.permission('plugin:team:query')")
    public Result<List<TeamUserVO>> pageQuery(@Valid TeamPageParam param) {
        String username = AuthUtils.getCurrentUsername();
        User user = userService.getByUsername(username);
        List<TeamUserVO> teamList = new ArrayList<>();
        teamList = teamService.listTeams(param, roleService.isAdmin(username));
        if(CollectionUtils.isEmpty(teamList)){
            return Result.success(teamList);
        }
        final List<Long> teamIdList = teamList.stream().map(TeamUserVO::getId).collect(Collectors.toList());
        // 判断当前用户是否已加入队伍
        QueryWrapper<UserTeam> userTeamQueryWrapper = new QueryWrapper<>();
        try {
            userTeamQueryWrapper.eq("user_id",user.getUserId());
            userTeamQueryWrapper.in("team_id",teamIdList);
            List<UserTeam> userTeamList = userTeamService.list(userTeamQueryWrapper);
            // 已加入的队伍id集合
            Set<Long> hasJoinTeamIdSet = userTeamList.stream().map(UserTeam::getTeamId).collect(Collectors.toSet());
            teamList.forEach(team -> {
                boolean hasJoin = hasJoinTeamIdSet.contains(team.getId());
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 查询已加入队伍的人数
        QueryWrapper<UserTeam> userTeamJoinQueryWrapper = new QueryWrapper<>();
        userTeamJoinQueryWrapper.in("team_id",teamIdList);
        List<UserTeam> userTeamList = userTeamService.list(userTeamJoinQueryWrapper);
        // 队伍id => 加入这个队伍的用户列表
        Map<Long, List<UserTeam>> teamIdUserTeamList = userTeamList.stream().collect(Collectors.groupingBy(UserTeam::getTeamId));
        teamList.forEach(team -> {
            team.setHasJoinNum(teamIdUserTeamList.getOrDefault(team.getId(),new ArrayList<>()).size());
        });

        return Result.success(teamList);

    }

    @PostMapping
    //@PreAuthorize("@auth.permission('plugin:team:add')")
    @ApiOperation("添加队伍")
    public Result<String> add(@RequestBody @Valid TeamAddParam param) {
        try {
            teamService.addTeam(param);
            return response(ApiEnum.ADD_SUCCESS);
        } catch (Exception e) {
            return failure(ApiEnum.ADD_ERROR, "新增队伍失败", e);
        }
    }

    @PutMapping
    //@PreAuthorize("@auth.permission('plugin:team:update')")
    @ApiOperation("修改队伍")
    public Result<String> update(@RequestBody @Valid TeamUpdateParam param) {
        try {
            teamService.updateTeam(param);
            return response(ApiEnum.UPDATE_SUCCESS);
        } catch (Exception e) {
            return failure(ApiEnum.UPDATE_ERROR, "更新队伍失败", e);
        }
    }

    @DeleteMapping("/{teamId}")
    //@PreAuthorize("@auth.permission('plugin:team:delete')")
    @ApiOperation("删除队伍")
    @ApiImplicitParam(name = "teamId", value = "队伍id", paramType = "path", required = true)
    public Result<String> deleteTeam(@PathVariable("teamId") String teamId) {
        try {
            teamService.deleteTeam(Long.valueOf(teamId));
            return response(ApiEnum.DELETE_SUCCESS);
        } catch (Exception e) {
            return failure(ApiEnum.DELETE_ERROR, e);
        }
    }
    @GetMapping("/get")
    public Result<Team> getTeamById(@RequestParam long id) {
        if (id <= 0) {
            return failure(ApiEnum.ERROR);
        }
        Team team = teamService.getById(id);
        if (team == null) {
            return failure("队伍id输入有误，查询失败");
        }
        return Result.success(team);
    }


    @GetMapping("/list/page")
    public Result<Page<Team>> listTeamsByPage(TeamPageParam teamPageParam) {
        if (teamPageParam == null) {
            return failure(ApiEnum.ERROR);
        }
        Team team = new Team();
        BeanUtils.copyProperties(teamPageParam,team);
        // 构造分页查询语句
        Page<Team> page = new Page<>(teamPageParam.getCurrent(),teamPageParam.getSize());
        QueryWrapper<Team> queryWrapper = new QueryWrapper<>(team);
        Page<Team> teamPage = teamService.page(page, queryWrapper);
        // 返回teamPage
        return Result.success(teamPage);
    }

    @PostMapping("/join")
    //@PreAuthorize("@auth.permission('plugin:team:join')")
    public Result<Boolean> joinTeam(@RequestBody TeamJoinRequest teamJoinRequest) throws ParseException {
        if (teamJoinRequest == null) {
            return failure(ApiEnum.ERROR);
        }
        return teamService.joinTeam(teamJoinRequest);
    }

    @PostMapping("/quit")
    //@PreAuthorize("@auth.permission('plugin:team:quit')")
    public Result<Boolean> quitTeam(@RequestBody TeamQuitRequest teamQuitRequest) {
        if (teamQuitRequest == null) {
            return failure(ApiEnum.ERROR);

        }
        return teamService.quitTeam(teamQuitRequest);
    }

    @GetMapping("/list/my/create")
    //@PreAuthorize("@auth.permission('plugin:team:query')")
    public Result<List<TeamUserVO>> listMyCreateTeams(TeamPageParam teamPageParam) {
        if (teamPageParam == null) {
            return failure(ApiEnum.ERROR);

        }
        String username = AuthUtils.getCurrentUsername();
        User user = userService.getByUsername(username);
        teamPageParam.setUserId(user.getUserId());
        List<TeamUserVO> teamList = teamService.listTeams(teamPageParam, true);
        return Result.success(teamList);
    }


    @GetMapping("/list/my/join")
    //@PreAuthorize("@auth.permission('plugin:team:query')")
    public Result<List<TeamUserVO>> listMyJoinTeams(TeamPageParam teamPageParam,HttpServletRequest request) {
        if (teamPageParam == null) {
            return failure(ApiEnum.ERROR);

        }
        String username = AuthUtils.getCurrentUsername();
        User user = userService.getByUsername(username);
        // 构造条件
        QueryWrapper<UserTeam> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",user.getUserId());
        List<UserTeam> userTeamList = userTeamService.list(queryWrapper);
        // 此时的userTeamList有该登录用户的创建队伍也有加入队伍
        // 所以还需要做一次过滤，将创建的队伍过滤掉

        // 取出不重复的队伍 id
        // teamId userId
        Map<Long,List<UserTeam>> listMap = userTeamList.stream().collect(Collectors.groupingBy(UserTeam::getTeamId));
        // 拿到所有不重复的teamID，并存储到List集合中
        List<Long> idList = new ArrayList<>(listMap.keySet());
        teamPageParam.setIdList(idList);
        // 根据teamId集合查询对应的队伍信息
        List<TeamUserVO> teamList = teamService.listTeams(teamPageParam, true);
        return Result.success(teamList);
    }


}
